package tech.wetech.admin3.sys.service;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import tech.wetech.admin3.config.WxAuthConfig;
import tech.wetech.admin3.sys.model.AooUser;
import tech.wetech.admin3.sys.repository.AooUserRepository;
import tech.wetech.admin3.util.AooJwtUtil;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;


@Service
@Slf4j
public class WxAuthService {
  @Autowired
  private AooJwtUtil jwtUtil;
  @Autowired
  private AooUserRepository userRepository;

  public AooUser login(String code) {
    log.info("微信授权小程序登录传参 code  {}", code);
    // 用code去微信服务器换取userInfo
    String appId = WxAuthConfig.appId;
    String appSecret = WxAuthConfig.appSecret;
    // 参数
    String params = "appid=" + appId + "&" +
      "secret=" + appSecret + "&" +
      "js_code=" + code + "&" +
      "grant_type=" + "authorization_code";

    RestTemplate restTemplate = new RestTemplate();
    String response = restTemplate.getForObject("https://api.weixin.qq.com/sns/jscode2session?" + params, String.class);
    JSONObject wxResponse = JSONObject.parseObject(response);
    log.info("微信授权小程序登录获取userInfo  {}", wxResponse);

    // 提取需要的信息保存到数据库
    String unionid = wxResponse.getString("unionid");
    String sessionKey = wxResponse.getString("session_key");

    if (unionid == null || sessionKey == null) {
      throw new RuntimeException(wxResponse.toString());
    }

    // 保存/更新 用户信息
    AooUser user = saveUser(unionid, sessionKey);
    String token = jwtUtil.generateTokenWx(unionid);
    user.setToken(token);

    return user;
  }

  @Transactional
  // 注册/更新 用户信息
  public AooUser saveUser(String unionid, String sessionKey) {
    // 检查数据库中是否已经有这个 unionid 字符串的Email
    AooUser user = userRepository.findByEmail(unionid);
    if (user == null) {
      // 如果没有，创建一个新的用户
      user = new AooUser();
      user.setEmail(unionid);
      user.setSessionKey(sessionKey);
      user = userRepository.save(user);   // 保存并重新获取user对象
    } else {
      // 如果已经有这个 unionid，更新 sessionKey
      user.setSessionKey(sessionKey);
      userRepository.save(user);
    }
    return user;
  }

  public JSONObject getPhoneNumber(String sessionKey, String encryptedData, String iv) {
    String session_key1 = sessionKey.replace(" ", "+");
    String encryptedData1 = encryptedData.replace(" ", "+");
    String iv1 = iv.replace(" ", "+");
    byte[] dataByte = Base64.decodeBase64(encryptedData1);
    byte[] keyByte = Base64.decodeBase64(session_key1);
    byte[] ivByte = Base64.decodeBase64(iv1);
    try {
      int base = 16;
      if (keyByte.length % base != 0) {
        int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
        byte[] temp = new byte[groups * base];
        Arrays.fill(temp, (byte) 0);
        System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
        keyByte = temp;
      }
      // 初始化
      Security.addProvider(new BouncyCastleProvider());
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
      SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
      AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
      parameters.init(new IvParameterSpec(ivByte));
      cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
      byte[] resultByte = cipher.doFinal(dataByte);
      if (null != resultByte && resultByte.length > 0) {
        String result = new String(resultByte, "UTF-8");
        return JSONObject.parseObject(result);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

}
